package network;

import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.Scanner;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class TcpEchoServer {
    private ServerSocket serverSocket = null;

    public TcpEchoServer(int port) throws IOException {
        serverSocket = new ServerSocket(port);  //操作模拟网卡的端口号
    }

    //启动服务器
    public void start() throws IOException {
        System.out.println("服务器启动了");
        //进入循环
        while (true) {
            //建立连接
            Socket Clientsocket = serverSocket.accept();
           /* Thread t=new Thread(()->{
                processClient(Clientsocket);
            });
            t.start();*/
            ExecutorService pool= Executors.newCachedThreadPool();
            pool.submit(new Runnable() {
                @Override
                public void run() {
                    try {
                        processClient(Clientsocket);
                    } catch (IOException e) {
                        throw new RuntimeException(e);
                    }
                }
            });
        }
    }

    private void processClient(Socket Clientsocket) throws IOException { //处理连接来的数据
        System.out.printf("[%s:%d] 客户端上线!\n", Clientsocket.getInetAddress(), Clientsocket.getPort());

        try (InputStream inputStream = Clientsocket.getInputStream();
             OutputStream OutputStream = Clientsocket.getOutputStream()) {
            //循环读取客户端的请求并且进行响应
            while (true) {
                Scanner scanner = new Scanner(inputStream);
                if (!scanner.hasNext()) {
                    System.out.printf("[%s:%d] 客户端下线!\n", Clientsocket.getInetAddress(), Clientsocket.getPort());
                    break;
                }
                String request = scanner.next();
                //进行响应操作
                String response = process(request);
                //将响应传给客户端
                //给outputstream进行外包装
                PrintWriter printWriter = new PrintWriter(OutputStream);
                printWriter.println(response);
                //上面这里的过程就是
                //OutputStream.write(response.getBytes(),0,response.getBytes().length);
                printWriter.flush();//刷新缓冲区，让数据发送出去

                System.out.printf("[%s:%d] req: %s, resp: %s\n",
                        Clientsocket.getInetAddress(),
                        Clientsocket.getPort(),
                        request,
                        response);

            }
        } catch (IOException e) {
            throw new RuntimeException(e);
        }finally {
            Clientsocket.close();//这里即每个clientsocket需要进行释放，否则会造成文件描述附表的占满
        }
    }

    public String process(String request) {
        return request;
    }

    public static void main(String[] args) throws IOException {
        TcpEchoServer server=new TcpEchoServer(3456);
        server.start();
    }
}

